package user

import (
	"encoding/json"
	"errors"
	"go-iot/app/models"
	"time"
	"go-iot/app/common/mysql"
	"gorm.io/gorm"
)

type RelType string

const (
	ResTypeRole RelType = "ROLE"
	ResTypeUser RelType = "USER"
)

// 分页查询角色
func PageRole(page *models.PageQuery, createId int64) (*models.PageResult[models.Role], error) {
	var roles []models.Role
	var count int64
	// 构建查询条件
	query := mysql.DB.Model(&models.Role{})
	
	// 添加过滤条件
	if len(page.Condition) > 0 {
		for _, term := range page.Condition {
			query = query.Where(term.Key+" = ?", term.Value)
		}
	}
	
	// 添加创建者ID过滤
	query = query.Where("create_id = ?", createId)
	
	// 如果有SearchAfter，添加相应条件
	if len(page.SearchAfter) > 0 && len(page.SearchAfter) >= 2 {
		query = query.Where("(create_time < ? OR (create_time = ? AND id < ?))", 
			page.SearchAfter[0], page.SearchAfter[0], page.SearchAfter[1])
	}
	
	// 计算总数
	err := query.Count(&count).Error
	if err != nil {
		return nil, err
	}
	
	// 查询数据
	err = query.Order("create_time DESC, id DESC").
		Limit(page.PageSize).
		Offset(page.PageOffset()).
		Find(&roles).Error
	if err != nil {
		return nil, err
	}
	
	// 获取最后一条记录的SearchAfter值
	var lastSort []interface{}
	if len(roles) > 0 {
		lastRole := roles[len(roles)-1]
		lastSort = []interface{}{lastRole.CreateTime, lastRole.Id}
	}
	
	// 构建分页结果
	result := models.PageUtil(count, page.PageNum, page.PageSize, roles)
	result.SearchAfter = lastSort
	
	return &result, nil
}

type RoleDTO struct {
	models.Role
	RuleRefMenus []struct {
		Code   string       `json:"code"`
		Action []MenuAction `json:"action"`
	} `json:"ruleRefMenus"`
}

func AddRole(ob *RoleDTO) error {
	// 检查名称是否已存在
	var existingRole models.Role
	result := mysql.DB.Where("name = ?", ob.Name).First(&existingRole)
	if result.Error == nil {
		return errors.New("名称已存在")
	} else if !errors.Is(result.Error, gorm.ErrRecordNotFound) {
		return result.Error
	}
	
	// 设置创建时间
	ob.CreateTime = time.Now()
	
	// 开启事务
	tx := mysql.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	
	// 插入角色数据
	if err := tx.Create(&ob.Role).Error; err != nil {
		tx.Rollback()
		return err
	}
	
	// 处理权限资源
	for _, m := range ob.RuleRefMenus {
		ar := models.AuthResource{}
		ac, err := json.Marshal(m.Action)
		if err != nil {
			tx.Rollback()
			return err
		}
		ar.Code = m.Code
		ar.ObjId = ob.Id
		ar.ResType = string(ResTypeRole)
		ar.Action = string(ac)
		ar.CreateTime = time.Now()
		
		// 插入权限资源
		if err := tx.Create(&ar).Error; err != nil {
			tx.Rollback()
			return err
		}
	}
	
	// 提交事务
	return tx.Commit().Error
}

func UpdateRole(ob *RoleDTO) error {
	// 开启事务
	tx := mysql.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	
	// 更新角色数据
	if err := tx.Model(&ob.Role).Updates(map[string]interface{}{
		"name": ob.Name,
		"desc": ob.Desc,
	}).Error; err != nil {
		tx.Rollback()
		return err
	}
	
	// 删除原有权限资源
	if err := tx.Where("type = ? AND obj_id = ?", string(ResTypeRole), ob.Id).Delete(&models.AuthResource{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	
	// 添加新的权限资源
	for _, m := range ob.RuleRefMenus {
		ar := models.AuthResource{}
		ac, err := json.Marshal(m.Action)
		if err != nil {
			tx.Rollback()
			return err
		}
		ar.Code = m.Code
		ar.ObjId = ob.Id
		ar.ResType = string(ResTypeRole)
		ar.Action = string(ac)
		ar.CreateTime = time.Now()
		
		// 插入权限资源
		if err := tx.Create(&ar).Error; err != nil {
			tx.Rollback()
			return err
		}
	}
	
	// 提交事务
	return tx.Commit().Error
}

func DeleteRole(ob *models.Role) error {
	// 开启事务
	tx := mysql.DB.Begin()
	defer func() {
		if r := recover(); r != nil {
			tx.Rollback()
		}
	}()
	
	// 删除角色关联的权限资源
	if err := tx.Where("type = ? AND obj_id = ?", string(ResTypeRole), ob.Id).Delete(&models.AuthResource{}).Error; err != nil {
		tx.Rollback()
		return err
	}
	
	// 删除角色
	if err := tx.Delete(ob).Error; err != nil {
		tx.Rollback()
		return err
	}
	
	// 提交事务
	return tx.Commit().Error
}

// deleteRoleAuth 函数可以移除，因为其功能已经整合到 DeleteRole 中

func GetRole(id int64) (*models.Role, error) {
	var role models.Role
	
	result := mysql.DB.First(&role, id)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, result.Error
	}
	
	return &role, nil
}

func GetRoleByEntity(p models.Role) (*models.Role, error) {
	var role models.Role
	query := mysql.DB.Model(&models.Role{})
	
	if p.Id != 0 {
		query = query.Where("id = ?", p.Id)
	}
	if len(p.Name) > 0 {
		query = query.Where("name = ?", p.Name)
	}
	
	result := query.First(&role)
	if result.Error != nil {
		if errors.Is(result.Error, gorm.ErrRecordNotFound) {
			return nil, nil
		}
		return nil, result.Error
	}
	
	return &role, nil
}

func AddAuthResource(ob *models.AuthResource) error {
	// 设置创建时间
	ob.CreateTime = time.Now()
	// 插入数据
	return mysql.DB.Create(ob).Error
}
